package com.bionic.banking.logic.controller;

import com.bionic.banking.core.entity.BankAccount;
import com.bionic.banking.core.entity.Customer;
import com.bionic.banking.dao.ICustomerDao;
import com.bionic.banking.dao.classes.CustomerDaoImpl;
import com.bionic.banking.dao.connection.LoggerLoader;
import com.bionic.banking.logic.ICustomerController;
import com.bionic.banking.logic.exception.InvalidParameterException;
import com.bionic.banking.logic.exception.TransactionTypeNotFoundException;
import java.sql.SQLException;
import java.util.*;
import org.apache.log4j.Logger;

public class CustomerController extends AbstractBean<Customer> implements ICustomerController {

    private static final Logger logger = LoggerLoader.getLogger(CustomerController.class);

    @Override
    protected ICustomerDao getDaoObject() {
        return new CustomerDaoImpl();
    }

    public CustomerController() throws InstantiationException, IllegalAccessException {
        super();
    }

    @Override
    public Boolean create(Customer entity) throws SQLException, InvalidParameterException {

        String error = null;
        if (entity.getFirstName() == null) {
            error = "null First name";
            logger.error(error);
            throw new InvalidParameterException(error);
        } else if (entity.getLastName() == null) {
            error = "null Last name";
            logger.error(error);
            throw new InvalidParameterException(error);
        } else {
            List<Customer> existList =
                    getDaoObject().findByFirstNameAndLastName(entity.getFirstName(), entity.getLastName());
            if (existList != null && existList.size() > 0) {
                error = "customer " + entity.getFirstName() + " " + entity.getLastName() + " already exists";
                logger.error(error);
                throw new InvalidParameterException(error);
            }
        }
        return super.create(entity);
    }

    @Override
    public void remove(Integer id) throws SQLException {
        Customer entity = getDetails(id);                
        //1. remove customer's bank accounts        
        BankAccountController bankaccountBean;
        try {
            bankaccountBean = new BankAccountController();
            bankaccountBean.removeCustomerAccounts(id);
        } catch (InvalidParameterException | InstantiationException | IllegalAccessException ex) {
            logger.error(ex);
            throw new SQLException(ex.getMessage());
        }
        //2. remove own customer
        super.remove(id);
        
        //3. remove related addressId
        int addressId = entity.getAddressId();
        AddressController addressBean;
        try {
            addressBean = new AddressController();
            addressBean.remove(addressId);
        } catch (InstantiationException | IllegalAccessException ex) {
            logger.error(ex);
            throw new SQLException(ex.getMessage());
        }        
        //4.remove related user
        int userId = entity.getUserId();
        UserController userBean;
        try {
            userBean = new UserController();
            userBean.remove(userId);
        } catch (InstantiationException | IllegalAccessException ex) {
            logger.error(ex);
            throw new SQLException(ex.getMessage());
        }
    }

    @Override
    public Customer getCustomerByUserId(Integer userId) throws SQLException, InvalidParameterException {
        List<Customer> allCustomers;
        try {
            allCustomers = getAll();
            for (Customer customer : allCustomers) {
                if (customer.getUserId().equals(userId)) {
                    return customer;
                }
            }
        } catch (SQLException ex) {
            logger.error(ex);
            throw new SQLException(ex);
        }
        return null;
    }

    @Override
    public List<Customer> getCustomersByEmail(String email) throws SQLException {
        return getDaoObject().findByEmail(email);
    }

    @Override
    public List<BankAccount> getCustomerAccounts(Integer customerId)
            throws SQLException, InstantiationException, InvalidParameterException,
            IllegalAccessException, TransactionTypeNotFoundException {
        return new BankAccountController().getCustomerAccounts(customerId);
    }
}
